﻿using SIAKADCORE.Helpers;
using SIAKADCORE.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIAKADCORE.Controllers
{
    /// <summary>
    /// Kelas UserController
    /// </summary>
    public class UserController
    {
        /// <summary>
        /// Method untuk menambahkan entri user dosen.
        /// </summary>
        /// <param name="user">Kelas User.</param>
        /// <param name="dosen">Kelas Dosen.</param>
        /// <returns>True ketika sukses menambahkan entri dan sebaliknya.</returns>
        public static bool Tambah(User user, Dosen dosen)
        {
            bool isDosenAccomplished = DosenController.Tambah(dosen);
            if (!isDosenAccomplished) return false;

            string queryString = string.Format("INSERT INTO {0} ({1} ,{2} ,{3} ,{4} ,{5} ,{6}, {7}) VALUES ('{8}' ,'{9}' ,'{10}' ,'{11}' ,'{12}' ,NULL, NULL)",
                User.TableName, User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,
                User.ColumnNameIdRole, User.ColumnNameIdDosen, User.ColumnNameIdMahasiswa, User.ColumnNameIdPegawai,
                user.IdUser, user.Username, user.Password, user.IdRole, user.IdDosen);

            bool isSuccess = SQLHelper.Instance.ExecuteNonQuery(queryString);
            if (!isSuccess)
            {
                DosenController.Hapus(dosen.IdDosen);
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// Method untuk menambahkan entri user mahasiswa.
        /// </summary>
        /// <param name="user">Kelas User.</param>
        /// <param name="mahasiswa">Kelas Mahasiswa.</param>
        /// <returns>True ketika sukses menambahkan entri dan sebaliknya.</returns>
        public static bool Tambah(User user, Mahasiswa mahasiswa)
        {
            bool isMahasiswaAccomplished = MahasiswaController.Tambah(mahasiswa);
            if (!isMahasiswaAccomplished) return false;

            string queryString = string.Format("INSERT INTO {0} ({1} ,{2} ,{3} ,{4} ,{5} ,{6}, {7}) VALUES ('{8}' ,'{9}' ,'{10}' ,'{11}' ,NULL ,'{12}', NULL)",
                User.TableName, User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,
                User.ColumnNameIdRole, User.ColumnNameIdDosen, User.ColumnNameIdMahasiswa, User.ColumnNameIdPegawai,
                user.IdUser, user.Username, user.Password, user.IdRole, user.IdMahasiswa);

            bool isSuccess = SQLHelper.Instance.ExecuteNonQuery(queryString);
            if (!isSuccess)
            {
                MahasiswaController.Hapus(mahasiswa.IdMahasiswa);
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// Method untuk menambahkan entri user pegawai.
        /// </summary>
        /// <param name="user">Kelas User.</param>
        /// <param name="pegawai">Kelas Pegawai.</param>
        /// <returns>True ketika sukses menambahkan entri dan sebaliknya.</returns>
        public static bool Tambah(User user, Pegawai pegawai)
        {
            bool isPegawaiAccomplished = PegawaiController.Tambah(pegawai);
            if (!isPegawaiAccomplished) return false;

            string queryString = string.Format("INSERT INTO {0} ({1} ,{2} ,{3} ,{4} ,{5} ,{6}, {7}) VALUES ('{8}' ,'{9}' ,'{10}' ,'{11}' ,NULL ,NULL, '{12}')",
                User.TableName, User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,
                User.ColumnNameIdRole, User.ColumnNameIdDosen, User.ColumnNameIdMahasiswa, User.ColumnNameIdPegawai,
                user.IdUser, user.Username, user.Password, user.IdRole, user.IdPegawai);

            bool isSuccess = SQLHelper.Instance.ExecuteNonQuery(queryString);
            if (!isSuccess)
            {
                PegawaiController.Hapus(pegawai.IdPegawai);
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// Method untuk mengubah role dari entri pengguna yang telah ada.
        /// </summary>
        /// <param name="idRoleBaru">Id role baru.</param>
        /// <param name="idUser">Id user yang akan diubah rolenya.</param>
        /// <returns>True ketika sukses mengubah id role dan sebaliknya.</returns>
        public static bool UbahRole(string idRoleBaru, string idUser)
        {
            string queryString = string.Format("UPDATE {0} SET {1} = '{2}' WHERE {3} = '{4}'",
                User.TableName, User.ColumnNameIdRole, idRoleBaru,
                User.ColumnNameIdUser, idUser);
            return SQLHelper.Instance.ExecuteNonQuery(queryString);
        }

        /// <summary>
        /// Method untuk menghapus entri pengguna.
        /// </summary>
        /// <param name="idUser">Id pengguna yang akan dihapus.</param>
        /// <returns>True ketika sukses menghapus entri dan sebaliknya.</returns>
        public static bool Hapus(string idUser)
        {
            string queryString = string.Format("DELETE FROM {0} WHERE {1} = '{2}'",
                User.TableName, User.ColumnNameIdUser, idUser);
            return SQLHelper.Instance.ExecuteNonQuery(queryString);
        }

        /// <summary>
        /// Method untuk mendapatkan hasil query dari tabel user.
        /// </summary>
        /// <param name="dataset">Dataset keluaran yang berisi hasil query.</param>
        /// <returns>True ketika sukses meng-query dan sebaliknya.</returns>
        public static bool GetTabel(out DataSet dataset)
        {
            string queryString = string.Format("SELECT {0} ,{1} ,{2} ,{3} ,{4} ,{5} FROM {6}",
                User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,
                User.ColumnNameIdRole, User.ColumnNameIdDosen, User.ColumnNameIdMahasiswa, User.TableName);
            return SQLHelper.Instance.ExecuteReader(queryString, out dataset);
        }

        /// <summary>
        /// Method untuk mendapatkan hasil query dari tabel user.
        /// </summary>
        /// <param name="dataset">Dataset keluaran yang berisi hasil query.</param>
        /// <returns>True ketika sukses meng-query dan sebaliknya.</returns>
        public static bool GetTabelPreview(out DataSet dataset)
        {
            string queryString = string.Format("SELECT [user].{0}, [user].{1}, [user].{2}, [role].{3} FROM {4}, {5} WHERE [user].{6} = [role].{7}",
                User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,Role.ColumnNameNamaRole,
                User.TableName, Role.TableName, User.ColumnNameIdRole, Role.ColumnNameIdRole);
            return SQLHelper.Instance.ExecuteReader(queryString, out dataset);
        }

        /// <summary>
        /// Method untuk mendapatkan hasil query dari tabel mahasiswa.
        /// </summary>
        /// <param name="dataset">Dataset keluaran yang berisi hasil query.</param>
        /// <param name="customQueryString">Kustomisasi query.</param>
        /// <returns>True ketika sukses meng-query dan sebaliknya.</returns>
        public static bool GetTabel(out DataSet dataset, string customQueryString)
        {
            return SQLHelper.Instance.ExecuteReader(customQueryString, out dataset);
        }
        
        /// <summary>
        /// Method untuk mendapatkan user dari tabel.
        /// </summary>
        /// <param name="idUser">Id user yang dicari.</param>
        /// <returns>Kelas User.</returns>
        public static User GetUser(string idUser)
        {
            var dataset = new DataSet();
            string queryString = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'",
                User.TableName, User.ColumnNameIdUser, idUser);
            bool isSuccess = SQLHelper.Instance.ExecuteReader(queryString, out dataset);
            if (!isSuccess)
            {
                return new User();
            }
            else
            {
                if (dataset.Tables[0].Rows.Count == 1)
                {
                    return new User
                    {
                        IdUser = dataset.Tables[0].Rows[0][0].ToString(),
                        Username = dataset.Tables[0].Rows[0][1].ToString(),
                        Password = dataset.Tables[0].Rows[0][2].ToString(),
                        IdRole = dataset.Tables[0].Rows[0][3].ToString(),
                        IdDosen = dataset.Tables[0].Rows[0][4].ToString(),
                        IdMahasiswa = dataset.Tables[0].Rows[0][5].ToString(),
                        IdPegawai = dataset.Tables[0].Rows[0][6].ToString()
                    };
                }
                else
                {
                    return new User();
                }
            }
        }

        /// <summary>
        /// Method untuk mengecek apakah username sudah terpakai atau belum
        /// </summary>
        /// <param name="username">Username yang akan dicek</param>
        /// <returns>True ketika username sudah terpakai</returns>
        public static bool CheckUsername(string username)
        {
            string queryString = string.Format("SELECT {0} ,{1} ,{2} ,{3} ,{4} ,{5}, {6} FROM {7} WHERE {1} = '{8}'",
                User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword,
                User.ColumnNameIdRole, User.ColumnNameIdDosen, User.ColumnNameIdMahasiswa,
                User.ColumnNameIdPegawai, User.TableName, username);
            
            var dataSet = new DataSet();
            SQLHelper.Instance.ExecuteReader(queryString, out dataSet);

            return dataSet.Tables[0].Rows.Count == 1;
        }

        /// <summary>
        /// Method untuk mencari username.
        /// </summary>
        /// <param name="username">Username yg dicari.</param>
        /// <param name="dataset">Dataset keluaran yang berisi hasil query.</param>
        /// <returns>True ketika sukses meng-query dan sebaliknya.</returns>
        public static bool Cari(string username, out DataSet dataset)
        {
            string queryString = string.Format("SELECT [user].{0}, [user].{1}, [user].{2}, [role].{3} FROM {4}, {5} WHERE [user].{6} = [role].{7} AND [user].{1} LIKE '%{8}%'",
                User.ColumnNameIdUser, User.ColumnNameUsername, User.ColumnNamePassword, Role.ColumnNameNamaRole,
                User.TableName, Role.TableName, User.ColumnNameIdRole, Role.ColumnNameIdRole, username);

            return GetTabel(out dataset, queryString);
        }

        /// <summary>
        /// Method untuk mendapatkan id mahasiswa. Digunakan pada saat memasukkan entri baru.
        /// </summary>
        /// <returns>string kosong ketika terjadi error atau id mahasiswa baru.</returns>
        public static string GetID()
        {
            var dataset = new DataSet();
            bool isQueryAccomplished = GetTabel(out dataset);
            if (!isQueryAccomplished) return string.Empty;

            return SQLHelper.Instance.GetID(User.IdPrefix, User.IdLength, ref dataset);
        }

        /// <summary>
        /// Method untuk mengubah password user.
        /// </summary>
        /// <param name="username">Username user yang passwordnya akan diganti.</param>
        /// <param name="passwordBaru">Password baru user.</param>
        /// <returns></returns>
        public static bool GantiPassword(string username, string passwordBaru)
        {
            bool isUserExist = CheckUsername(username);
            if (!isUserExist) return false;

            string queryString = string.Format("UPDATE {0} SET {1} = {2} WHERE {3} = {4}",
                User.TableName, User.ColumnNamePassword, passwordBaru,
                User.ColumnNameUsername, username);

            return SQLHelper.Instance.ExecuteNonQuery(queryString);
        }

        /// <summary>
        /// Method untuk mendapatkan id role.
        /// </summary>
        /// <param name="username">username.</param>
        /// <returns>String kosong jika tidak ditemukan atau id role.</returns>
        public static string GetRole(string username)
        {
            var dataset = new DataSet();
            string queryString = string.Format("SELECT {0} FROM {1} WHERE {2} = '{3}'",
                User.ColumnNameIdRole, User.TableName,
                User.ColumnNameUsername, username);
            bool isSuccess = GetTabel(out dataset, queryString);

            if (!isSuccess)
            {
                return string.Empty;
            }
            else
            {
                return dataset.Tables[0].Rows[0][0].ToString();
            }
        }
    }
}
